#include "window.h"
#include "vortex/event/events.h"

namespace vortex
{
	static void window_resize_callback(GLFWwindow* window, int newWidth, int newHeight)
	{
		glViewport(0, 0, newWidth, newHeight);
	}

	static void mouse_move_callback(GLFWwindow* window, double xpos, double ypos)
	{
		static float xpos_prev = 0;
		static float ypos_prev = 0;
		static bool moved = false;

		Event event;
		event.type = EventType::EVENT_MOUSE_MOVE;
		float xoff, yoff;

		if (!moved)
		{
			xoff = 0;
			yoff = 0;
			moved = true;
			xpos_prev = xpos;
			ypos_prev = ypos;
		}
		else
		{
			xoff = xpos - xpos_prev;
			yoff = ypos_prev - ypos;
			xpos_prev = xpos;
			ypos_prev = ypos;
		}
		event.context.data.f32[0] = xoff;
		event.context.data.f32[1] = yoff;
		event.handled = false;
		fire_event(event, nullptr);
	}

	Window::Window(uint32_t width, uint32_t height, const std::string& title)
		:_width(width), _height(height), _title(title)
	{
		// initialize glfw
		glfwInit();
		glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
		glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
		glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
		glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

		_window = glfwCreateWindow(_width, _height, _title.c_str(), NULL, NULL);
		glfwMakeContextCurrent(_window);
		
		// initialize glew
		if (glewInit() != GLEW_OK)
			exit(EXIT_FAILURE);

		glfwSwapInterval(1);
		glfwSetWindowSizeCallback(_window, window_resize_callback);
		glfwSetCursorPosCallback(_window, mouse_move_callback);
		glfwSetWindowUserPointer(_window, this);
	}

	Window::~Window()
	{
		glfwDestroyWindow(_window);
		glfwTerminate();
	}

	bool Window::closed() const
	{
		return glfwWindowShouldClose(_window);
	}

	void Window::update(float dt)
	{
		glfwPollEvents();
		glfwSwapBuffers(_window);
	}
}
